﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using APC.Common;

namespace APC
{
    class Locations
    {

        #region Declarations

        private DataHandlingDataContext ctx;

        #endregion

        #region Properties

        public int LocationId
        {
            get { return this._LocationId; }
            set { this._LocationId = value; }
        }
        private int _LocationId;

        public int LocationTypeId
        {
            get { return this._LocationTypeId; }
            set { this._LocationTypeId = value; }
        }
        private int _LocationTypeId;

        public int RawMaterialId
        {
            get { return this._RawMaterialId; }
            set { this._RawMaterialId = value; }
        }
        private int _RawMaterialId = 0;

        public string RawMaterialName
        {
            get { return this._RawMaterialName; }
            set { this._RawMaterialName = value; }
        }
        private string _RawMaterialName = "";

        public string RawMaterialNumber
        {
            get { return this._RawMaterialNumber; }
            set { this._RawMaterialNumber = value; }
        }
        private string _RawMaterialNumber = "";

        public String ColorMap
        {
            get { return this._ColorMap; }
            set { this._ColorMap = value; }
        }
        private String _ColorMap;

        public String LocationName
        {
            get { return this._LocationName; }
            set { this._LocationName = value; }
        }
        private String _LocationName;

        public String Description
        {
            get { return this._Description; }
            set { this._Description = value; }
        }
        private String _Description;

        public float MaxVolume
        {
            get { return this._MaxVolume; }
            set { this._MaxVolume = value; }
        }
        private float _MaxVolume;

        public float MinVolume
        {
            get { return this._MinVolume; }
            set { this._MinVolume = value; }
        }
        private float _MinVolume;

        public float Volume
        {
            get { return this._Volume; }
            set { this._Volume = value; }
        }
        private float _Volume;


        public bool Active
        {
            get { return this._Active; }
            set { this._Active = value; }
        }
        private bool _Active;

        public int LocationPosition
        {
            get { return this._LocationPosition; }
            set { this._LocationPosition = value; }
        }
        private int _LocationPosition;

        public int TagListeGroupId
        {
            set { _TagListeGroupId = value; }
            get { return _TagListeGroupId; }
        }
        private int _TagListeGroupId = 0;

        /// <summary>
        /// Returns full list of all locations
        /// </summary>
        public List<APC.Common.Location> LocationList
        {
            set { this._LocationList = value; }
            get { return this._LocationList; }
        }
        private List<APC.Common.Location> _LocationList;

        /// <summary>
        /// Returns full list of all location groups
        /// </summary>
        public List<APC.Common.Location> LocationGroupList
        {
            set { this._LocationGroupList = value; }
            get { return this._LocationGroupList; }
        }
        private List<APC.Common.Location> _LocationGroupList;

        /// <summary>
        /// Returns full list of all location groups
        /// </summary>
        public List<APC.Common.LocationsType> LocationTypes
        {
            set { this._LocationTypes = value; }
            get { return this._LocationTypes; }
        }
        private List<APC.Common.LocationsType> _LocationTypes;

        /// <summary>
        /// Flag true if user has changed raw material on selected location (unit)
        /// </summary>
        public bool RawMateralChanged
        {
            set { _RawMaterialChanged = value ;}
            get { return _RawMaterialChanged ;}
        }
        private bool _RawMaterialChanged = false;

        #endregion

        #region Constructors

        public Locations(int LocationId)
        {
            this._LocationId = LocationId;
            this.LoadLocation();
        }

        /// <summary>
        /// Empty constructor
        /// </summary>
        public Locations()
        {  

        }

        /// <summary>
        /// Initiate load og LocationList and LocationGroupList
        /// </summary>
        /// <param name="LoadLists"></param>
        public Locations(bool LoadLists)
        {
            this.LoadLocationList();
            this.LoadLocationTypes();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Loads properties of selected Location
        /// </summary>
        private void LoadLocation()
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            using (ctx)
            {
                var loc = (from l in ctx.Locations.Where(x => x.Id == _LocationId)
                           from t in ctx.TagListGroups
                           where l.TagListeGroupId == t.Id
                           select new
                           {
                                Name = l.Name,
                                MaxVolume = l.MaxVolume,
                                MinVolume = l.MinVolume,
                                Active = l.Active,
                                Description = l.Description,
                                LocationPosition = l.LocationPosition,
                                TagListeGroupId = l.TagListeGroupId,
                                Volume = l.Volume,
                                LocationTypeId = l.LocationTypeId,
                                ColorMap = t.ColorMap
                           }).FirstOrDefault();

                var raw = (from rm in ctx.RawMaterialsLocations
                           from r in ctx.RawMaterials
                           where rm.RawMateralId == r.Id && rm.LocationsId == _LocationId
                           select new {
                               Id = r.Id,
                               Name = r.Name,
                               Number = r.MaterialNumber
                           }).FirstOrDefault();
            
                    this._LocationName = loc.Name.Trim();
                    this._MaxVolume = Convert.ToInt64(loc.MaxVolume);
                    this._MinVolume = Convert.ToInt64(loc.MinVolume);
                    this._Active = Convert.ToBoolean(loc.Active);
                    this._Description = loc.Description;
                    this._LocationPosition = Convert.ToInt32(loc.LocationPosition);
                    this._TagListeGroupId = Convert.ToInt32(loc.TagListeGroupId);
                    this._Volume = Convert.ToInt64(loc.Volume);
                    this._LocationTypeId = Convert.ToInt32(loc.LocationTypeId);
                    this._ColorMap = loc.ColorMap;

                    if (raw != null)
                    {
                        this._RawMaterialId = raw.Id;
                        this._RawMaterialName = raw.Name;
                        this._RawMaterialNumber = raw.Number;
                    }
              

                LoadLocationTypes();
            }

            ctx.Dispose();
        }

        /// <summary>
        /// Returns a full list of all Locations
        /// </summary>
        /// <returns></returns>
        public void LoadLocationList()
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

           // List<APC.Common.Location> LocationList = new List<APC.Common.Location>();

            using (ctx)
            {
   
                var query = (from l in ctx.Locations
                             orderby l.TagListeGroupId
                             orderby l.LocationPosition
                             select l).ToList<APC.Common.Location>();

                _LocationList = query; // ctx.Locations.ToList<APC.Common.Location>(); //query.ToList<APC.Common.Location>();
                             
            }
        }

        /// <summary>
        /// Returns full list of all location groups
        /// </summary>
        private void LoadLocationTypes()
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            using (ctx)
            {
                var query = (from var3 in ctx.LocationsTypes
                             select var3).ToList<APC.Common.LocationsType>();

                this._LocationTypes = query; //.ToList<APC.Common.LocationsType>();
            }

        }

        /// <summary>
        /// Test method: set selected location to have a negative volume
        /// </summary>
        /// <param name="LocationId"></param>
        public void SetVolumeNegative(int LocationId)
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            ctx.ExecuteCommand("UPDATE Locations SET Volume = -165 WHERE Id = " + LocationId.ToString());

        }

        /// <summary>
        /// Test method: set selected location to have a volume = max volume
        /// </summary>
        /// <param name="LocationId"></param>
        public void SetVolumeReset(int LocationId)
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            ctx.ExecuteCommand("UPDATE Locations SET Volume = MaxVolume WHERE Id = " + LocationId.ToString());

        }

        /// <summary>
        /// Test method: Set Volume to Max Volume
        /// </summary>
        public void SetVolumneToMaxVolume()
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            ctx.ExecuteCommand("UPDATE Locations SET Volume = MaxVolume");

        }



        public void Save()
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            APC.Common.Location l = ctx.Locations.Where(x => x.Id ==_LocationId).FirstOrDefault();
            

            if (l != null)
            {
                l.MaxVolume = _MaxVolume;
                l.MinVolume = _MinVolume;
                l.Volume = _Volume;
                l.Name = _LocationName;
                l.TagListeGroupId = _TagListeGroupId;
                l.LocationPosition = _LocationPosition;

                if (_RawMaterialChanged == true) //User has changed the raw material for selected location (unit)
                {
                    //Delete other erealtion between selected location and rawmaterial
                    APC.Common.RawMaterialsLocation loc = ctx.RawMaterialsLocations.Where(x => x.LocationsId == _LocationId).SingleOrDefault();
                    if (loc != null)
                    {
                        ctx.RawMaterialsLocations.DeleteOnSubmit(loc);
                    }
                  

                    //Insert new relation between selected location and rawmaterial
                    APC.Common.RawMaterialsLocation lc = new APC.Common.RawMaterialsLocation();
                    lc.LocationsId = _LocationId;
                    lc.RawMateralId = _RawMaterialId;
                    ctx.RawMaterialsLocations.InsertOnSubmit(lc);
                   
                }

                ctx.SubmitChanges();
            }       
        }


        #endregion

    }
}
